﻿using System;  // 引入基础命名空间

 // 地图元素符号常量定义
    const char WALL = '#';    // 墙壁（不可通行）
    const char PATH = '.';    // 路径（可行走区域）
    const char PLAYER = 'P';  // 玩家当前位置
    const char EXIT = 'E';    // 出口（胜利目标）

   
        // 生成5x5地图（实际存储为一维数组）
        char[] map = GenerateMap(5, 5);  
        // 玩家初始位置设置为索引6（对应二维坐标 y=1, x=1）
        int playerPos = 6;  
        bool gameRunning = true;  // 游戏运行状态控制

        // 主游戏循环
        while (gameRunning)
        {
            RenderMap(map, 5, 5);  // 渲染当前地图状态
            Console.WriteLine("使用 WASD 移动，Q 退出");
            Console.Write("请输入操作：");  // 输入提示
            
            // 获取用户按键（intercept:false 表示显示按键输入）
            var input = Console.ReadKey(intercept: false).Key;  
            Console.WriteLine();  // 换行保持界面整洁

            // 根据输入执行对应操作
            switch (input)
            {
                case ConsoleKey.W:  // 上移（Y轴-1）
                    TryMove(0, -1); 
                    break;
                case ConsoleKey.S:  // 下移（Y轴+1）
                    TryMove(0, 1);  
                    break;
                case ConsoleKey.A:  // 左移（X轴-1）
                    TryMove(-1, 0); 
                    break;
                case ConsoleKey.D:  // 右移（X轴+1）
                    TryMove(1, 0);  
                    break;
                case ConsoleKey.Q:  // 退出游戏
                    gameRunning = false; 
                    break;
                default:  // 处理无效输入
                    Console.WriteLine("无效输入！"); 
                    Console.ReadKey();  // 暂停等待用户确认
                    break;
            }
        }

        // ========== 核心移动逻辑方法 ==========
        void TryMove(int dx, int dy)  // dx: X轴变化量，dy: Y轴变化量
        {
            int width = 5;  // 地图宽度（与GenerateMap参数一致）
            
            // 将一维索引转换为二维坐标
            int currentY = playerPos / width;  // 计算当前行号
            int currentX = playerPos % width; // 计算当前列号

            // 计算新坐标
            int newX = currentX + dx;
            int newY = currentY + dy;
            int newPos = newY * width + newX;  // 二维坐标转一维索引

            // 边界检查（确保新坐标在0~4范围内）
            if (newX < 0 || newX >= width || newY < 0 || newY >= width)
                return;  // 越界则取消移动

            // 碰撞检测（检查目标位置是否为墙壁）
            if (map[newPos] == WALL)
                return;  // 遇到障碍物则取消移动

            // 更新玩家位置
            map[playerPos] = PATH;    // 原位置恢复为路径
            playerPos = newPos;       // 更新玩家位置索引
            map[playerPos] = PLAYER;  // 新位置标记为玩家

            // 胜利条件检测（是否到达出口）
            if (map[newPos] == EXIT)
            {
                Console.WriteLine("找到出口！游戏胜利！");
                gameRunning = false;  // 结束游戏循环
            }
        }
    

    // ========== 地图生成方法 ==========
    static char[] GenerateMap(int width, int height)
    {
        // 创建一维数组存储地图（总长度=width*height）
        char[] map = new char[width * height];  
        
        // 预定义地图布局（使用数字编码）
        // 0: 路径(PATH), 1: 墙壁(WALL), 2: 出口(EXIT)
        int[] layout = {
            1,1,1,0,2,  // 第0行
            1,0,0,0,1,  // 第1行（玩家初始位置在此行）
            1,0,1,0,1,  // 第2行
            1,0,0,0,1,  // 第3行
            1,1,1,1,1   // 第4行
        };

        // 根据layout数组生成地图符号
        for (int i = 0; i < map.Length; i++)
        {
            map[i] = layout[i] switch  // 模式匹配转换
            {
                0 => PATH,
                1 => WALL,
                2 => EXIT,
                _ => PATH  // 默认值处理
            };
        }

        map[6] = PLAYER;  // 设置玩家初始位置（第1行第2列）
        return map;
    }

    // ========== 地图渲染方法 ==========
    static void RenderMap(char[] map, int width, int height)
    {
        Console.Clear();  // 清空控制台
        
        // 遍历每行每列渲染地图
        for (int y = 0; y < height; y++)      // 行循环
        {
            for (int x = 0; x < width; x++)   // 列循环
            {
                // 计算一维索引：index = y * 行宽度 + x
                int index = y * width + x;  
                Console.Write(map[index] + " ");  // 输出地图元素+空格
            }
            Console.WriteLine();  // 换行开始下一行
        }
    }
